package dfs_bfs;

import java.util.*;

public class lc1462 {
    public static void main(String[] args) {
        System.out.println(checkIfPrerequisite3(2, new int[][]{{1,0}}, new int[][]{{0,1},{1,0}}));
    }

    /**
     * floyd 算法
     * @param numCourses
     * @param prerequisites
     * @param queries
     * @return
     */
    public static List<Boolean> checkIfPrerequisite2(int numCourses, int[][] prerequisites, int[][] queries) {
        boolean[][] adj = new boolean[numCourses][numCourses];
        for (int i = 0; i < prerequisites.length; i++) {
            adj[prerequisites[i][0]][prerequisites[i][1]] = true;
        }
        for (int i = 0; i < numCourses; i++) {
            for (int j = 0; j < numCourses; j++) {
                for (int k = 0; k < numCourses; k++) {
                    adj[j][k] = adj[j][k] || (adj[j][i] && adj[i][k]);
                }
            }
        }
        List<Boolean> list = new ArrayList<>();
        for (int i = 0; i < queries.length; i++) {
            list.add(adj[queries[i][0]][queries[i][1]]);
        }
        return list;
    }


    /**
     * bfs
     * @param numCourses
     * @param prerequisites
     * @param queries
     * @return
     */
    public static List<Boolean> checkIfPrerequisite3(int numCourses, int[][] prerequisites, int[][] queries) {
        boolean[][] adj = new boolean[numCourses][numCourses];
        int[] pre = new int[numCourses];
        for (int i = 0; i < prerequisites.length; i++) {
            adj[prerequisites[i][0]][prerequisites[i][1]] = true;
            pre[prerequisites[i][1]]++;
        }
        Queue<Integer> queue = new LinkedList<>();
        for (int i = 0; i < numCourses; i++) {
            if(pre[i] == 0)
                queue.offer(i);
        }
        while (!queue.isEmpty()){
            int t = queue.poll();
            for (int i = 0; i < numCourses; i++) {
                if(adj[t][i]){
                    for (int j = 0; j < numCourses; j++) {
                        if(adj[j][t])
                            adj[j][i] = true;
                    }
                }
                pre[i]--;
                if (pre[i] == 0)
                    queue.offer(i);
            }
        }
        List<Boolean> list = new ArrayList<>();
        for (int i = 0; i < queries.length; i++) {
            list.add(adj[queries[i][0]][queries[i][1]]);
        }
        return list;
    }



    public static List<Boolean> checkIfPrerequisite(int numCourses, int[][] prerequisites, int[][] queries) {
        List<List<Integer>> pre = new ArrayList<>();
        for (int i = 0; i < numCourses; i++) {
            pre.add(new ArrayList<>());
        }
        for (int i = 0; i < prerequisites.length; i++) {
            pre.get(prerequisites[i][0]).add(prerequisites[i][1]);
        }
        List<Boolean> re = new ArrayList<>();
        for (int i = 0; i < queries.length; i++) {
            if(dfs(queries[i][0], queries[i][1], pre))
                re.add(true);
            else
                re.add(false);
        }
        return re;
    }
    public static boolean dfs(int b, int e, List<List<Integer>> pre){
        List<Integer> list = pre.get(b);
        if(list.contains(e))
            return true;
        if(list.size() == 0)
            return false;
        for (Integer integer : list) {
            if (dfs(integer, e, pre))
                return true;
        }
        return false;
    }
}
